package juc.ProducerCnosumer;

/**
 * @author 马迪迪
 * @description: TODO
 * @data 2025年09月15日22时42分
 * 生产者消费者多线程，购买商品Demo
 *
 * 店家，又一个店家有三种商品（苹果、香蕉、草莓）每种商品都有数量，价格，店家最多能接受每种库存数最大为50。
 *
 * 生产者：开始，店家的三种商品都为空，生产者开始生产，每个生产者生产产品需要10s时间。且生产完成时只能按生产前店家所缺少的库存数进行生产，没种商品都有独立的生产商（可以采用设计模式中工厂模式），厂家给商家有自己单独的价格，给每个厂家所获利的钱进行统计。
 *
 * 消费者：当消费者来店里购买，可以同时有多个消费者来进行消费，当有多个消费者对统一产品进行消费后面的消费者需等待。进店消费者人数每次总数不能超过8位（每次可以采用随机数进行人数，当店里有未消费完成的消减人数到店里最大人数）且每个消费者随机消费商品类型和数量（每个消费者消费商品数最大不能超过10）。若无该商品，可以重置该消费者选择的商品类型和数量，或者当前消费者直接结束。
 *
 * 规定一天为5分钟，最后吧每一天生产者出售的商品数量，价格做统计在控制台显示打印。商家，统计每种商品消费的数量，价格，成功消费人数，和消费失败人数。每天都做统计打印。
 *
 * 增加需求：消费者在消费时，生产者未生产出产品该部分缺少消费者在消费失败时应该立马触发该产品生产
 */
public class TestMain {
    private static final long DAY_DURATION = 5 * 60 * 1000; // 一天5分钟（毫秒）

    public static void main(String[] args) throws InterruptedException {
        // 1. 初始化店家
        Store store = new Store();

        // 2. 创建生产者（每种商品1个生产者，共3个）
        Thread appleProducer = GoodsProducerFactory.createProducer(store, Goods.APPLE);
        Thread bananaProducer = GoodsProducerFactory.createProducer(store, Goods.BANANA);
        Thread strawberryProducer = GoodsProducerFactory.createProducer(store, Goods.STRAWBERRY);

        // 3. 创建消费者（20个线程，由信号量控制最多8个同时消费）
        Thread[] consumers = new Thread[20];
        for (int i = 0; i < consumers.length; i++) {
            consumers[i] = new Thread(new Consumer(store), "消费者" + (i + 1));
        }

        // 4. 启动所有线程
        appleProducer.start();
        bananaProducer.start();
        strawberryProducer.start();
        for (Thread consumer : consumers) {
            consumer.start();
        }
        System.out.println("===== 营业开始（持续5分钟） =====");

        // 5. 模拟一天营业时长
        Thread.sleep(DAY_DURATION);

        // 6. 停止营业，等待线程结束
        store.stop();
        appleProducer.join();
        bananaProducer.join();
        strawberryProducer.join();
        for (Thread consumer : consumers) {
            consumer.join();
        }

        // 7. 打印当日统计
        store.printDailyStat();
    }
}
